package com.base.cn.platform.os.controller.web.order.pay;

import com.base.cn.platform.os.common.WebBaseController;
import com.base.cn.platform.os.common.constants.CacheConstants;
import com.base.cn.platform.os.common.constants.CommonConstants;
import com.base.cn.platform.os.common.constants.ConfigName;
import com.base.cn.platform.os.common.j2cache.CustomCacheChannel;
import com.base.cn.platform.os.common.j2cache.J2CacheRegion;
import com.base.cn.platform.os.common.utils.ObjectUtils;
import com.base.cn.platform.os.common.utils.order.OrderSource;
import com.base.cn.platform.os.common.utils.order.OrderStatus;
import com.base.cn.platform.os.common.utils.order.PayType;
import com.base.cn.platform.os.common.utils.pay.AlipayUtils;
import com.base.cn.platform.os.common.utils.pay.PayFormClient;
import com.base.cn.platform.os.common.utils.pay.PayService;
import com.base.cn.platform.os.common.utils.pay.WeiXinUtils;
import com.base.cn.platform.os.common.utils.pay.config.PlayCallbackParams;
import com.base.cn.platform.os.common.utils.result.ResultUtil;
import com.base.cn.platform.os.entity.order.order.OrderType;
import com.base.cn.platform.os.service.manage.config.SysConfigService;
import com.base.cn.platform.os.service.manage.order.goods.OrderService;
import com.base.cn.platform.os.service.manage.order.pay.PayOrderCallbackService;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

/**
 * 订单支付Controller
 *
 * @author s.li
 * @create 2018-06-20-10:46
 */
@Controller
@Slf4j
public class WebPayController extends WebBaseController {

    @Autowired
    private OrderService orderService;
    @Autowired
    private PayOrderCallbackService payOrderCallbackService;
    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private CustomCacheChannel customCacheChannel;
    @Autowired
    private CommonConstants commonConstants;


    /**
     * 跳转支付
     * @param request HttpServletRequest
     * @param payType 支付类型
     * @param orderNo 订单号
     * @param orderType 订单类型
     * @param price 价格（用于充值）
     * @return
     */
    @RequestMapping("/web/uc/pay/gotoPay")
    public String gotoPay(HttpServletRequest request,
                          Model model,
                          @RequestParam(value = "payType") String payType,
                          @RequestParam(value = "orderNo") String orderNo,
                          @RequestParam(value = "orderType",required = false,defaultValue = "COMMON") String orderType,
                          @RequestParam(value = "price",required = false,defaultValue = "0") double price,
                          RedirectAttributes attributes) throws Exception{
        BigDecimal userId = webMobileLoginUtil.getLoginUserId(request);
        Map<String,Object> _res = orderService.checkWebOrderData(userId,orderNo,orderType,payType,price);
        if(!ResultUtil.getSuccess(_res)){//如果订单验证失败
            String message = ResultUtil.getMessage(_res);
            attributes.addAttribute("message",message);
            return redirect(request,"/web/pay/payMessage?orderNo="+orderNo);
        }
        //得到订单对象
        Map<String,Object> order = (Map<String,Object>)ResultUtil.getEntity(_res);
        //账户支付(只能普通订单可以账户支付)
        if(payType.equals(PayType.PAY_TYPE_ACCOUNT) && orderType.equals(OrderType.COMMON.getKey())){
            Map<String,Object> payCallback = PlayCallbackParams.getPayCallbackParams(PayType.PAY_TYPE_ACCOUNT,
                    OrderType.COMMON.getKey(),orderNo,null,userId,"0",OrderSource.ORDER_FORM_WEB);
            Map<String,Object> resultMap = payOrderCallbackService.payCallback(payCallback);
            return payReturn(request,orderNo,resultMap,attributes);
        }
        PayService payService;
        //获取支付配置
        TreeMap<String,String> payConfigMap = sysConfigService.getSysConfigContext(ConfigName.PAY);
        Map<String,String> params = new HashMap<>();
        params.put("orderNo",orderNo);
        params.put("userId",userId.toString());
        params.put("totalAmount",order.get("realPrice").toString());
        params.put("describe",order.get("shopNames").toString());
        String contextUrl = commonConstants.get(CommonConstants.WEB_PATH);
        //同步回调路径
        params.put("returnUrl",contextUrl + "/web/pay/paySuccessCallback/"+payType+"/"+orderType+"/"+orderNo+"/"+userId+"/1");
        //异步回调路径
        params.put("notifyUrl", contextUrl + "/web/pay/paySuccessCallback/"+payType+"/"+orderType+"/"+orderNo+"/"+userId+"/2");
        Map<String,Object> resultMap = null;
        if(payType.equals(PayType.PAY_TYPE_ALIPAY)){//支付宝支付
            payService = new AlipayUtils();
            resultMap = payService.goToPay(request,payConfigMap,params, PayFormClient.PC);
            if(ResultUtil.getSuccess(resultMap)){
                model.addAttribute("fromContext",ResultUtil.getEntity(resultMap));
                return resultPage("/order/pay/order-alipay");
            }
        }
        if(payType.equals(PayType.PAY_TYPE_WEIXIN)){//微信支付
            payService = new WeiXinUtils();
            resultMap = payService.goToPay(request,payConfigMap,params, PayFormClient.PC);
            if(ResultUtil.getSuccess(resultMap)){
                model.addAttribute("orderNo",orderNo);
                model.addAttribute("resultMap",resultMap);
                return resultPage("/order/pay/order-weixinBuy");
            }
        }
        String message = "系统错误，支付失败";
        if(resultMap!=null && !ResultUtil.getSuccess(resultMap)){//获取错误信息
            message = ResultUtil.getMessage(resultMap);
        }
        attributes.addAttribute("message",message);
        return redirect(request,"/web/pay/payMessage?orderNo="+orderNo);
    }

    /**
     * 支付回调
     * @param request HttpServletRequest
     * @param response HttpServletResponse
     * @param payType 支付类型
     * @param orderType 订单类型
     * @param orderNo 订单号
     * @param userId 用户ID
     * @param type 类型，1同步，2异步
     * @return
     */
    @RequestMapping("/web/pay/paySuccessCallback/{payType}/{orderType}/{orderNo}/{userId}/{type}")
    public String paySuccessCallback(HttpServletRequest request,
                                     HttpServletResponse response,
                                     @PathVariable String payType,
                                     @PathVariable String orderType,
                                     @PathVariable String orderNo,
                                     @PathVariable BigDecimal userId,
                                     @PathVariable int type,
                                     RedirectAttributes attributes) throws Exception{
        log.info("----------------------payType:"+payType);
        if(type==1){//同步
            Map<String, Object> result = ResultUtil.SUCCESS("支付成功");
            return payReturn(request,orderNo,result,attributes);
        }
        PayService payService = null;
        Map<String,String> resultMap = null;
        TreeMap<String,String> payConfigMap = sysConfigService.getSysConfigContext(ConfigName.PAY);
        if(payType.equals(PayType.PAY_TYPE_ALIPAY)){//支付宝支付
            payService = new AlipayUtils();
        }
        if(payType.equals(PayType.PAY_TYPE_WEIXIN)){//微信支付
            payService = new WeiXinUtils();
        }

        if(ObjectUtils.isNotEmpty(payService)){
            resultMap = payService.payCallback(request,response,payConfigMap,PayFormClient.PC);
        }
        if(resultMap.get("success").equals("true")){//验证成功
                Map<String,Object> payCallback = PlayCallbackParams.getPayCallbackParams(payType,orderType,orderNo,resultMap.get("treadNo"),userId,resultMap.get("amount"),OrderSource.ORDER_FORM_MOBILE);
                log.info("======================传给订单的回调数据："+payCallback);
                Map<String,Object> result = payOrderCallbackService.payCallback(payCallback);
                log.info("======================订单回调数据："+result);
        }
        return  null;
    }


    /**
     * 支付成功提示页面
     * @param model
     * @param orderNo 订单号
     * @param type 类型，1错误，2成功
     * @param message 提示信息
     * @return 提示页面
     */
    @RequestMapping("/web/pay/payMessage")
    public String payMessage(Model model,
                             HttpServletRequest request,
                             @RequestParam("orderNo") String orderNo,
                             @RequestParam(value = "type",required = false,defaultValue = "1") int type,
                             @RequestParam(value = "message",required = false) String message){
        BigDecimal userId = webMobileLoginUtil.getLoginUserId(request);
        String classesUrl = (String) customCacheChannel.get(J2CacheRegion.THIRD_MINUTE_REGION.getKey(), CacheConstants.USER_BUY_COURSE_JOIN_CLASS + userId.toString()).getValue();
        customCacheChannel.evict(J2CacheRegion.THIRD_MINUTE_REGION.getKey(), CacheConstants.USER_BUY_COURSE_JOIN_CLASS + userId.toString());
        Map<String,Object> order = orderService.findOrderBuyNo(orderNo);
        model.addAttribute("order",order);
        model.addAttribute("orderNo",orderNo);
        model.addAttribute("type",type);
        model.addAttribute("message",message);
        model.addAttribute("classesUrl",classesUrl);
        return resultPage("/order/pay/pay-message");
    }

    /**
     * 验证订单状态
     * @param request
     * @param orderNo 订单号
     * @return Map<String,Object>
     */
    @RequestMapping("/web/uc/pay/verificationOrderStatus")
    @ResponseBody
    public Map<String,Object> verificationOrderStatus(HttpServletRequest request,
                                                      @RequestParam("orderNo") String orderNo){
        Map<String,Object> order = orderService.findOrderBuyNo(orderNo);
        Object orderStatus = OrderStatus.INIT;
        if(ObjectUtils.isNotEmpty(order)){
            orderStatus = order.get("orderStatus");
        }
        return ResultUtil.SUCCESS(orderStatus);
    }

    /**
     * 获取支付后跳转路径URL
     * @param request
     * @param orderNo
     * @param result
     * @param attributes
     * @return
     */
    private String payReturn(HttpServletRequest request,String orderNo,
                             Map<String,Object> result,RedirectAttributes attributes){
        String message = ResultUtil.getMessage(result);
        attributes.addAttribute("message",message);
        if(ResultUtil.getSuccess(result)){
            attributes.addAttribute("type",2);
        }
        return redirect(request,"/web/pay/payMessage?orderNo="+orderNo);
    }
}
